implement more of N4258 - Cleaning up noexcept in the standard library. Specifically add new noexcept stuff to vector and string's move-assignment operations git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@245330 91177308-0d34-0410-b5e6-96231b3b80d8 
diff --git a/include/memory b/include/memory index df35a07..790a161 100644 --- a/include/memory +++ b/include/memory 
@@ -5574,6 +5574,15 @@  _LIBCPP_INLINE_VISIBILITY  void __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {}   +template <typename _Alloc, typename _Traits=allocator_traits<_Alloc>> +struct __noexcept_move_assign_container : public integral_constant<bool,  + _Traits::propagate_on_container_move_assignment::value +#if _LIBCPP_STD_VER > 14 + || _Traits::is_always_equal::value +#else + && is_nothrow_move_assignable<_Alloc>::value +#endif + > {};    _LIBCPP_END_NAMESPACE_STD   diff --git a/include/string b/include/string index 2c677ce..372522c 100644 --- a/include/string +++ b/include/string 
@@ -115,8 +115,8 @@  basic_string& operator=(const basic_string& str);  basic_string& operator=(basic_string&& str)  noexcept( - allocator_type::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value); + allocator_type::propagate_on_container_move_assignment::value || + allocator_type::is_always_equal::value ); // C++17  basic_string& operator=(const value_type* s);  basic_string& operator=(value_type c);  basic_string& operator=(initializer_list<value_type>); @@ -1377,8 +1377,7 @@  #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES  _LIBCPP_INLINE_VISIBILITY  basic_string& operator=(basic_string&& __str) - _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value); + _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));  #endif  _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s) {return assign(__s);}  basic_string& operator=(value_type __c); @@ -1845,11 +1844,16 @@    #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES  _LIBCPP_INLINE_VISIBILITY - void __move_assign(basic_string& __str, false_type); + void __move_assign(basic_string& __str, false_type) + _NOEXCEPT_(__alloc_traits::is_always_equal::value);  _LIBCPP_INLINE_VISIBILITY  void __move_assign(basic_string& __str, true_type) +#if _LIBCPP_STD_VER > 14 + _NOEXCEPT; +#else  _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);  #endif +#endif    _LIBCPP_INLINE_VISIBILITY  void @@ -2430,6 +2434,7 @@  inline _LIBCPP_INLINE_VISIBILITY  void  basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type) + _NOEXCEPT_(__alloc_traits::is_always_equal::value)  {  if (__alloc() != __str.__alloc())  assign(__str); @@ -2441,7 +2446,11 @@  inline _LIBCPP_INLINE_VISIBILITY  void  basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type) +#if _LIBCPP_STD_VER > 14 + _NOEXCEPT +#else  _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) +#endif  {  clear();  shrink_to_fit(); @@ -2454,8 +2463,7 @@  inline _LIBCPP_INLINE_VISIBILITY  basic_string<_CharT, _Traits, _Allocator>&  basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str) - _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value) + _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))  {  __move_assign(__str, integral_constant<bool,  __alloc_traits::propagate_on_container_move_assignment::value>()); diff --git a/include/vector b/include/vector index 049d3c8..1cafae1 100644 --- a/include/vector +++ b/include/vector 
@@ -51,8 +51,8 @@  vector& operator=(const vector& x);  vector& operator=(vector&& x)  noexcept( - allocator_type::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value); + allocator_type::propagate_on_container_move_assignment::value || + allocator_type::is_always_equal::value); // C++17  vector& operator=(initializer_list<value_type> il);  template <class InputIterator>  void assign(InputIterator first, InputIterator last); @@ -175,8 +175,8 @@  vector& operator=(const vector& x);  vector& operator=(vector&& x)  noexcept( - allocator_type::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value); + allocator_type::propagate_on_container_move_assignment::value || + allocator_type::is_always_equal::value); // C++17  vector& operator=(initializer_list<value_type> il);  template <class InputIterator>  void assign(InputIterator first, InputIterator last); @@ -562,9 +562,7 @@  vector(vector&& __x, const allocator_type& __a);  _LIBCPP_INLINE_VISIBILITY  vector& operator=(vector&& __x) - _NOEXCEPT_( - __alloc_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value); + _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));  #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES  #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS  _LIBCPP_INLINE_VISIBILITY @@ -787,7 +785,8 @@  void __move_range(pointer __from_s, pointer __from_e, pointer __to);  void __move_assign(vector& __c, true_type)  _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value); - void __move_assign(vector& __c, false_type); + void __move_assign(vector& __c, false_type) + _NOEXCEPT_(__alloc_traits::is_always_equal::value);  _LIBCPP_INLINE_VISIBILITY  void __destruct_at_end(pointer __new_last) _NOEXCEPT  { @@ -1303,9 +1302,7 @@  inline _LIBCPP_INLINE_VISIBILITY  vector<_Tp, _Allocator>&  vector<_Tp, _Allocator>::operator=(vector&& __x) - _NOEXCEPT_( - __alloc_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value) + _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))  {  __move_assign(__x, integral_constant<bool,  __alloc_traits::propagate_on_container_move_assignment::value>()); @@ -1315,6 +1312,7 @@  template <class _Tp, class _Allocator>  void  vector<_Tp, _Allocator>::__move_assign(vector& __c, false_type) + _NOEXCEPT_(__alloc_traits::is_always_equal::value)  {  if (__base::__alloc() != __c.__alloc())  { @@ -2213,9 +2211,7 @@  vector(vector&& __v, const allocator_type& __a);  _LIBCPP_INLINE_VISIBILITY  vector& operator=(vector&& __v) - _NOEXCEPT_( - __alloc_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value); + _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));  #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES  #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS  _LIBCPP_INLINE_VISIBILITY @@ -2838,9 +2834,7 @@  inline _LIBCPP_INLINE_VISIBILITY  vector<bool, _Allocator>&  vector<bool, _Allocator>::operator=(vector&& __v) - _NOEXCEPT_( - __alloc_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value) + _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))  {  __move_assign(__v, integral_constant<bool,  __storage_traits::propagate_on_container_move_assignment::value>());